const zero = (n: number, max: number) => {
    let s = n.toString(16).toUpperCase();
    while (s.length < max) {
        s = '0' + s;
    }
    return s;
};

export const printBuffer = (buffer: Uint8Array) => {
    const rows = Math.ceil(buffer.length / 16);
    const last = buffer.length % 16 || 16;
    let offsetLength = buffer.length.toString(16).length;
    if (offsetLength < 6) offsetLength = 6;

    let str = 'Offset';
    while (str.length < offsetLength) {
        str += ' ';
    }

    str = '\u001b[36m' + str + '  ';

    let i;
    for (i = 0; i < 16; i++) {
        str += ' ' + zero(i, 2);
    }

    str += '\u001b[0m\n';
    if (buffer.length) str += '\n';

    let b = 0;
    let lastBytes;
    let lastSpaces;
    let v;

    for (i = 0; i < rows; i++) {
        str += '\u001b[36m' + zero(b, offsetLength) + '\u001b[0m  ';
        lastBytes = i === rows - 1 ? last : 16;
        lastSpaces = 16 - lastBytes;

        let j;
        for (j = 0; j < lastBytes; j++) {
            str += ' ' + zero(buffer[b], 2);
            b++;
        }

        for (j = 0; j < lastSpaces; j++) {
            str += '   ';
        }

        b -= lastBytes;
        str += '   ';

        for (j = 0; j < lastBytes; j++) {
            v = buffer[b];
            str += (v > 31 && v < 127) || v > 159 ? String.fromCharCode(v) : '.';
            b++;
        }

        str += '\n';
    }

    console.log(str);
};
